import os
import zipfile
import tkinter as tk
from tkinter import messagebox, scrolledtext
import mmap


def decrypt_file(path):
    original_file_path = path
    modified_file_path = 'modified.ini'
    target_file_path = 'output_file.ini'

    # 重命名原始文件
    os.rename(original_file_path, modified_file_path)

    # 使用 mmap 读取文件内容
    with open(modified_file_path, 'rb') as source_file:
        with mmap.mmap(source_file.fileno(), 0, access=mmap.ACCESS_READ) as mmapped_file:
            content = bytes(mmapped_file)

    # 如果目标文件存在，则删除它
    if os.path.exists(target_file_path):
        os.remove(target_file_path)

    # 将内容写入目标文件
    with open(target_file_path, 'wb') as target_file:
        target_file.write(content)

    # 删除临时文件
    os.remove(modified_file_path)

    # 重命名目标文件为原始文件名
    os.rename(target_file_path, original_file_path)

    # 打开原始文件并返回文件句柄
    file_handle = open(original_file_path, 'rb')
    return file_handle


target_extensions = [
    'decrypt.exe',
    'decode.exe',
    'decode.py',
    '文件解密工具.py'
]


# # 解密文件并保持文件被占用
# def decrypt_file(path):
#     original_file_path = path
#     modified_file_path = 'modified.ini'
#     target_file_path = 'output_file.ini'
#     os.rename(original_file_path, modified_file_path)
#     with open(modified_file_path, 'rb') as source_file:
#         content = source_file.read()
#     if os.path.exists(target_file_path):
#         os.remove(target_file_path)
#     with open(target_file_path, 'wb') as target_file:
#         target_file.write(content)
#     os.remove(modified_file_path)
#     os.rename(target_file_path, original_file_path)
#     print(original_file_path)
#     file_handle = open(original_file_path, 'rb')
#     return file_handle

# 检查文件名是否符合要求
def check_file(name):
    for extension in target_extensions:
        if name.endswith(extension):
            return False
    return True


def decrypt_folder(folder_path):
    file_handles = []
    for root, _, files in os.walk(folder_path):
        for filename in files:
            if not check_file(filename):
                continue
            file_path = os.path.join(root, filename)
            show_name = "\'" + filename + "\',"
            output(show_name)
            if os.path.isfile(file_path):
                file_handle = decrypt_file(file_path)
                file_handles.append(file_handle)
    return file_handles


def zip_folder(folder_path, output_zip_path):
    with zipfile.ZipFile(output_zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
        for root, _, files in os.walk(folder_path):
            for file in files:
                if check_file(file):
                    file_path = os.path.join(root, file)
                    arcname = os.path.relpath(file_path, folder_path)
                    zipf.write(file_path, arcname)


global global_file_handle
global_file_handle = None


def execute():
    global global_file_handle

    # 关闭旧的文件句柄
    if global_file_handle is not None:
        global_file_handle.close()
        global_file_handle = None

    zip_name = command_entry.get() + '.zip'
    if zip_name not in target_extensions:
        target_extensions.append(zip_name)

    current_folder = os.getcwd()
    file_handles = decrypt_folder(current_folder)
    output_zip_path = os.path.join(current_folder, zip_name)
    zip_folder(current_folder, output_zip_path)
    output(f"文件已解密并打包到 {output_zip_path}")
    zip_path = output_zip_path
    print(zip_path)

    # 打开新的文件句柄
    try:
        global_file_handle = open(zip_path, 'rb')
    except IOError as e:
        output(f"无法打开文件 {zip_path}: {e}")
        global_file_handle = None


# 创建主窗口
root = tk.Tk()
root.title("加密文件破解_N0974143朱锦涛v1.5")

# 创建一个 Label 来显示固定的文字
label = tk.Label(root, text="不要轻易改解密应用名，否则会一起打包", font=("Arial", 12))
label.pack(pady=0)
# 创建一个 Label 来显示固定的文字
label = tk.Label(root, text="将需要解密的文件/文件夹和这个软件一起丢一个文件夹内", font=("Arial", 12))
label.pack(pady=0)
# 创建一个 Label 来显示固定的文字
label = tk.Label(root, text="然后点击按钮即可,然后把生成的压缩包发给别人", font=("Arial", 12))
label.pack(pady=0)
# 创建一个 Label 来显示固定的文字
label = tk.Label(root, text="下方输入压缩包名称", font=("Arial", 12))
label.pack(pady=0)
# 创建输入命令的文本框
command_entry = tk.Entry(root, width=50)
command_entry.pack(pady=10)
command_entry.insert(0, "请输入压缩包名称")
# 创建一个 Label 来显示固定的文字
output_text = scrolledtext.ScrolledText(root, wrap=tk.WORD, width=80, height=15)
output_text.pack(pady=10)
# root.iconbitmap('icon2.ico')
# 创建一个 Frame 来管理按钮
button_frame = tk.Frame(root)
button_frame.pack(pady=10)


def output(text):
    output_text.insert(tk.END, text + '\n')
    output_text.see(tk.END)


def get_message(command):
    try:
        # 执行命令并捕获输出
        result = subprocess.run(command, check=True, capture_output=True, text=True, shell=True, encoding='utf-8')
        output_text.delete(1.0, tk.END)  # 清空文本框
        output_text.insert(tk.END, filter_special_chars(result.stdout))  # 插入命令输出
    except subprocess.CalledProcessError as e:
        output_text.delete(1.0, tk.END)  # 清空文本框
        output_text.insert(tk.END, f"命令执行失败: {filter_special_chars(e.stderr.strip())}")  # 插入错误信息


# 创建查看设备的按钮
preset_command_button = tk.Button(button_frame, text="破解、打包文件", command=execute)
preset_command_button.pack(side=tk.TOP, pady=10)

# 运行主循环
root.mainloop()
